#ifndef SCI_H
#define SCI_H

#ifdef __cplusplus
extern "C" {
#endif

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C" {
#endif

//*****************************************************************************
//
//! \addtogroup sci_api SCI
//! @{
//
//*****************************************************************************

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_sci.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "cpu.h"
#include "debug.h"
#include "sysctl.h"

#include "f28004x_device.h"

//*****************************************************************************
//
// Values that can be passed to SCI_enableInterrupt, SCI_disableInterrupt, and
// SCI_clearInterruptStatus as the intFlags parameter, and returned from
// SCI_getInterruptStatus.
//
//*****************************************************************************
#define SCI_INT_RXRDY 0x01U //!< RXRDY interrupt
#define SCI_INT_TXRDY 0x02U //!< TXRDY interrupt
#define SCI_INT_RXFF  0x01U //!< RX FIFO level interrupt
#define SCI_INT_TXFF  0x02U //!< TX FIFO level interrupt
#define SCI_INT_RXERR 0x04U //!< Recv Line Status interrupt
#define SCI_INT_FE    0x04U //!< Frame Error
#define SCI_INT_OE    0x04U //!< Overrun Error
#define SCI_INT_PE    0x04U //!< Parity Error

//*****************************************************************************
//
// Values that can be passed to SCI_setConfig as the config parameter
// and returned by SCI_getConfig in the config parameter.
// Additionally, the SCI_CONFIG_PAR_* enum subset can be passed to
// SCI_setParityMode as the parity parameter, and are returned by
// SCI_getParityMode.
//
//*****************************************************************************
#define SCI_CONFIG_WLEN_MASK 0x0003U //!< Mask for extracting word length
#define SCI_CONFIG_WLEN_8    0x0003U //!< 8 bit data
#define SCI_CONFIG_WLEN_7    0x0002U //!< 7 bit data
#define SCI_CONFIG_WLEN_6    0x0001U //!< 6 bit data
#define SCI_CONFIG_WLEN_5    0x0000U //!< 5 bit data
#define SCI_CONFIG_STOP_MASK 0x0004U //!< Mask for extracting stop bits
#define SCI_CONFIG_STOP_ONE  0x0000U //!< One stop bit
#define SCI_CONFIG_STOP_TWO  0x0004U //!< Two stop bits
#define SCI_CONFIG_PAR_MASK  0x0018U //!< Parity Mask

//*****************************************************************************
//
//! Values that can be used with SCI_setParityMode() and SCI_getParityMode() to
//! describe the parity of the SCI communication.
//
//*****************************************************************************
typedef enum
{
    SCI_CONFIG_PAR_NONE = 0x0000U, //!< No parity
    SCI_CONFIG_PAR_EVEN = 0x0018U, //!< Even parity
    SCI_CONFIG_PAR_ODD  = 0x0008U  //!< Odd parity
} SCI_ParityType;

//*****************************************************************************
//
//! Values that can be passed to SCI_setFIFOInterruptLevel() as the txLevel
//! parameter and returned by SCI_getFIFOInteruptLevel() and
//! SCI_getTxFIFOStatus().
//
//*****************************************************************************
typedef enum
{
    SCI_FIFO_TX0 = 0x0000U, //!< Transmit interrupt empty
    SCI_FIFO_TX2 = 0x0001U, //!< Transmit interrupt 2 char
    SCI_FIFO_TX4 = 0x0002U, //!< Transmit interrupt 1/4 full
    SCI_FIFO_TX8 = 0x0003U, //!< Transmit interrupt 1/2 full
} SCI_TxFIFOLevel;

//*****************************************************************************
//
//! Values that can be passed to SCI_setFIFOInterruptLevel() as the rxLevel
//! parameter and returned by SCI_getFIFOInterruptLevel() and
//! SCI_getRxFIFOStatus().
//
//*****************************************************************************
typedef enum
{
    SCI_FIFO_RX1  = 0x0000U, //!< Receive interrupt 1 char
    SCI_FIFO_RX4  = 0x0001U, //!< Receive interrupt 1/4 full
    SCI_FIFO_RX8  = 0x0002U, //!< Receive interrupt 1/2 full
    SCI_FIFO_RX14 = 0x0003U, //!< Receive interrupt when 2 less than full in rx FIFO
} SCI_RxFIFOLevel;

//*****************************************************************************
//
//*****************************************************************************
typedef enum
{
    SCI_INT_SATUS_MODEM_STATUS = 0x00U, // modem status interrupt
    SCI_INT_SATUS_NONE         = 0x01U, // no interrupt pending
    SCI_INT_SATUS_TXRDY        = 0x02U, // tx ready interrupt
    SCI_INT_SATUS_RXRDY        = 0x04U, // rx ready interrupt
    SCI_INT_SATUS_LINE_STATUS  = 0x06U, // recieiver line interrupt
    SCI_INT_SATUS_BUSY         = 0x07U, // busy dectect interrupt
    SCI_INT_SATUS_RXTIMEROUT   = 0x0CU, // character timerout interrupt
} SCI_IntStatusType;

#define SCI_RXSTATUS_ERROR 0x001EU //!< Receiver error

//*****************************************************************************
//
// Values returned from SCI_getRxStatus().  These correspond to the different
// bits and flags of the SCILSR register.
//
//*****************************************************************************
#define SCI_RXSTATUS_READY     0x0001U //!< Receiver ready
#define SCI_RXSTATUS_OVERRUN   0x0002U //!< Overrun error
#define SCI_RXSTATUS_PARITY    0x0004U //!< Parity error
#define SCI_RXSTATUS_FRAMING   0x0008U //!< Framing error
#define SCI_RXSTATUS_BREAK     0x0010U //!< Break detect
#define SCI_RXSTATUS_ADDR_RCVD 0x0100U //!< Address Received detect (in 9-bit mode)

//*****************************************************************************
//
// API Function prototypes
//
//*****************************************************************************
//*****************************************************************************
//
//! \internal
//! Checks a SCI base address.
//!
//! \param base is the base address of the SCI port.
//!
//! This function determines if a SCI port base address is valid.
//!
//! \return Returns \b true if the base address is valid and \b false
//! otherwise.
//
//*****************************************************************************
#ifdef DEBUG
static inline bool SCI_isBaseValid(uint32_t base)
{
    return ((base == SCIA_BASE) || (base == SCIB_BASE));
}
#endif

//*****************************************************************************
//
//! Sets the type of parity.
//!
//! \param base is the base address of the SCI port.
//! \param parity specifies the type of parity to use.
//!
//! Sets the type of parity to use for transmitting and expect when receiving.
//! The \e parity parameter must be one of the following:
//! \b SCI_CONFIG_PAR_NONE, \b SCI_CONFIG_PAR_EVEN, \b SCI_CONFIG_PAR_ODD.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_setParityMode(uint32_t base, SCI_ParityType parity)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Set the parity mode.
    //
    HWREG(base + SCI_O_LCR)
        = ((HWREG(base + SCI_O_LCR) & ~(SCI_CONFIG_PAR_MASK)) | (uint16_t)parity);
}

//*****************************************************************************
//
//! Gets the type of parity currently being used.
//!
//! \param base is the base address of the SCI port.
//!
//! This function gets the type of parity used for transmitting data and
//! expected when receiving data.
//!
//! \return Returns the current parity settings, specified as one of the
//! following:
//! \b SCI_CONFIG_PAR_NONE, \b SCI_CONFIG_PAR_EVEN, \b SCI_CONFIG_PAR_ODD.
//
//*****************************************************************************
static inline SCI_ParityType SCI_getParityMode(uint32_t base)
{
    uint16_t parity;

    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return the current parity setting.
    //
    parity = (HWREG(base + SCI_O_LCR) & (SCI_CONFIG_PAR_MASK));

    return ((SCI_ParityType)parity);
}

//*****************************************************************************
//
//! Sets the multiprocessor protocol to address-bit mode.
//!
//! \param base is the base address of the SCI port.
//!
//! This function sets the multi-processor protocol to address-bit mode.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_setAddrMultiProcessorMode(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Enable the address-bit mode protocol
    //
    HWREG(base + SCI_O_LCR_EXT) |= SCI_LCR_EXT_DLS_E;
}

//*****************************************************************************
//
//! Sets the FIFO interrupt level at which interrupts are generated.
//!
//! \param base is the base address of the SCI port.
//! \param txLevel is the transmit FIFO interrupt level, specified as one of
//! the following:
//! \b SCI_FIFO_TX0, \b SCI_FIFO_TX2, \b SCI_FIFO_TX4, \b SCI_FIFO_TX8.
//! \param rxLevel is the receive FIFO interrupt level, specified as one of
//! the following
//! \b SCI_FIFO_RX1, \b SCI_FIFO_RX4, \b SCI_FIFO_RX8, \b SCI_FIFO_RX14.
//!
//! This function sets the FIFO level at which transmit and receive interrupts
//! are generated.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_setFIFOInterruptLevel(
    uint32_t base, SCI_TxFIFOLevel txLevel, SCI_RxFIFOLevel rxLevel)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Set the FIFO interrupt levels.
    //
    // WANING: FCR is write only register!
    HWREG(base + SCI_O_FCR)
        = (SCI_FCR_FIFOE | (rxLevel << SCI_FCR_RCVR_S) | (txLevel << SCI_FCR_TET_S));
}

//*****************************************************************************
//
//! Enables the transmit and receive FIFOs.
//! Note: This interface will reset the transmit water level, receive water level configuration, and
//! you need to reconfigure the transmit water level, receive water level after calling this
//! interface)
//!
//! \param base is the base address of the SCI port.
//!
//! This functions enables the transmit and receive FIFOs in the SCI.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_enableFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Enable the FIFO.
    //
    // WANING: FCR is write only register!
    HWREG(base + SCI_O_FCR) = SCI_FCR_FIFOE;
}

//*****************************************************************************
//
//! Disables the transmit and receive FIFOs.
//! Note: This interface will reset the transmit water level, receive water level configuration, and
//! you need to reconfigure the transmit water level, receive water level after calling this
//! interface)
//!
//! \param base is the base address of the SCI port.
//!
//! This functions disables the transmit and receive FIFOs in the SCI.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_disableFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Disable the FIFO.
    //
    // WANING: FCR is write only register!
    HWREG(base + SCI_O_FCR) = 0;
}

//*****************************************************************************
//
//! Determines if the FIFO enhancement is enabled.
//!
//! \param base is the base address of the SCI port.
//!
//! This function returns a flag indicating whether or not the FIFO enhancement
//! is enabled.
//!
//! \return Returns \b true if the FIFO enhancement is enabled or \b false
//! if the FIFO enhancement is disabled.
//
//*****************************************************************************
static inline bool SCI_isFIFOEnabled(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return true if the FIFO is enabled and false if it is disabled.
    //
    return ((HWREG(base + SCI_O_IIR) & SCI_IIR_FIFO_EN_M) == 0 ? false : true);
}

//*****************************************************************************
//
//! Resets the receive FIFO.
//! Note: This interface will reset the transmit water level, receive water level configuration, and
//! you need to reconfigure the transmit water level, receive water level after calling this
//! interface)
//!
//! \param base is the base address of the SCI port.
//!
//! This functions resets the receive FIFO of the SCI.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_resetRxFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Reset the specified FIFO.
    //
    // WANING: FCR is write only register!
    HWREG(base + SCI_O_FCR) = SCI_FCR_RFIFOR;
}

//*****************************************************************************
//
//! Resets the transmit FIFO.
//! Note: This interface will reset the transmit water level, receive water level configuration, and
//! you need to reconfigure the transmit water level, receive water level after calling this
//! interface)
//!
//! \param base is the base address of the SCI port.
//!
//! This functions resets the transmit FIFO of the SCI.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_resetTxFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Reset the specified FIFO.
    //
    // WANING: FCR is write only register!
    HWREG(base + SCI_O_FCR) = SCI_FCR_XFIFOR;
}

//*****************************************************************************
//
//! Resets the SCI Transmit and Receive Channels
//! Note: This interface will reset the transmit water level, receive water level configuration, and
//! you need to reconfigure the transmit water level, receive water level after calling this
//! interface)
//!
//! \param base is the base address of the SCI port.
//!
//! This functions resets transmit and receive channels in the SCI.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_resetChannels(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Reset the Tx and Rx Channels
    //
    // WANING: FCR is write only register!
    HWREG(base + SCI_O_FCR) = SCI_FCR_XFIFOR | SCI_FCR_RFIFOR;
}

//*****************************************************************************
//
//! Determines if there are any characters in the receive buffer when the
//! FIFO enhancement is not enabled.
//!
//! \param base is the base address of the SCI port.
//!
//! This function returns a flag indicating whether or not there is data
//! available in the receive buffer.
//!
//! \return Returns \b true if there is data in the receive buffer or \b false
//! if there is no data in the receive buffer.
//
//*****************************************************************************
static inline bool SCI_isDataAvailableNonFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return the availability of characters with FIFO disabled.
    //
    return (HWREG(base + SCI_O_LSR) & SCI_LSR_DR);
}

//*****************************************************************************
//
//! Determines if there is any space in the transmit buffer when the FIFO
//! enhancement is not enabled.
//!
//! \param base is the base address of the SCI port.
//!
//! This function returns a flag indicating whether or not there is space
//! available in the transmit buffer when not using the FIFO enhancement.
//!
//! \return Returns \b true if there is space available in the transmit buffer
//! or \b false if there is no space available in the transmit buffer.
//
//*****************************************************************************
static inline bool SCI_isSpaceAvailableNonFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return the availability of space.
    //
    return (HWREG(base + SCI_O_LSR) & SCI_LSR_THRE);
}

//*****************************************************************************
//
//! Get the transmit FIFO status
//!
//! \param base is the base address of the SCI port.
//!
//! This functions gets the current number of words in the transmit FIFO.
//!
//! \return Returns the current number of words in the transmit FIFO specified
//
//*****************************************************************************
static inline uint16_t SCI_getTxFIFOStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Get the current FIFO status
    //
    return HWREG(base + SCI_O_TFL);
}

//*****************************************************************************
//
//! Get the receive FIFO status
//!
//! \param base is the base address of the SCI port.
//!
//! This functions gets the current number of words in the receive FIFO.
//!
//! \return Returns the current number of words in the receive FIFO specified
//
//*****************************************************************************
static inline uint16_t SCI_getRxFIFOStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Get the current FIFO status
    //
    return HWREG(base + SCI_O_RFL);
}

//*****************************************************************************
//
//! Determines whether the SCI transmitter is busy or not.
//!
//! \param base is the base address of the SCI port.
//!
//! Allows the caller to determine whether all transmitted bytes have cleared
//! the transmitter hardware when the FIFO is not enabled.  When the FIFO is
//! enabled, this function allows the caller to determine whether there is any
//! data in the FIFO.
//!
//! Without the FIFO enabled, if \b false is returned, the transmit buffer and
//! shift registers are empty and the transmitter is not busy. With the FIFO
//! enabled, if \b false is returned, the FIFO is empty.  This does not
//! necessarily mean that the transmitter is not busy.  The empty FIFO does not
//! reflect the status of the transmitter shift register. The FIFO may be empty
//! while the transmitter is still transmitting data.
//!
//! \return Returns \b true if the SCI is transmitting or \b false if
//! transmissions are complete.
//
//*****************************************************************************
static inline bool SCI_isTransmitterBusy(uint32_t base)
{
    //
    // Check the argument.
    //
    ASSERT(SCI_isBaseValid(base));

    if (SCI_isFIFOEnabled(base))
        return (HWREG(base + SCI_O_TFL) != 0);
    else
        return HWREG(base + SCI_O_LSR) & SCI_LSR_TEMT;
}

//*****************************************************************************
//
//! Waits to send a character from the specified port when the FIFO enhancement
//! is enabled.
//!
//! \param base is the base address of the SCI port.
//! \param data is the character to be transmitted.
//!
//! Sends the character \e data to the transmit buffer for the specified port.
//! If there is no space available in the transmit FIFO, this function waits
//! until there is space available before returning. \e data is a uint16_t but
//! only 8 bits are written to the SCI port.  SCI only transmits 8 bit
//! characters.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_writeCharBlockingFIFO(uint32_t base, uint16_t data)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Wait until space is available in the transmit FIFO.
    //
    while (SCI_getTxFIFOStatus(base) == 16)
    { }

    //
    // Send a char.
    //
    HWREG(base + SCI_O_THR) = data;
}

//*****************************************************************************
//
//! Waits to send a character from the specified port.
//!
//! \param base is the base address of the SCI port.
//! \param data is the character to be transmitted.
//!
//! Sends the character \e data to the transmit buffer for the specified port.
//! If there is no space available in the transmit buffer, or the transmit
//! FIFO if it is enabled, this function waits until there is space available
//! before returning. \e data is a uint16_t but only 8 bits are written to the
//! SCI port.  SCI only transmits 8 bit characters.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_writeCharBlockingNonFIFO(uint32_t base, uint16_t data)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Wait until space is available in the transmit buffer.
    //
    while (!SCI_isSpaceAvailableNonFIFO(base))
    { }

    //
    // Send a char.
    //
    HWREG(base + SCI_O_THR) = data;
}

//*****************************************************************************
//
//! Sends a character to the specified port.
//!
//! \param base is the base address of the SCI port.
//! \param data is the character to be transmitted.
//!
//! Writes the character \e data to the transmit buffer for the specified port.
//! This function does not block and only writes to the transmit buffer.
//! The user should use SCI_isSpaceAvailableNonFIFO() or SCI_getTxFIFOStatus()
//! to determine if the transmit buffer or FIFO have space available.
//! \e data is a uint16_t but only 8 bits are written to the SCI port.  SCI
//! only transmits 8 bit characters.
//!
//! This function replaces the original SCICharNonBlockingPut() API and
//! performs the same actions.  A macro is provided in <tt>sci.h</tt> to map
//! the original API to this API.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_writeCharNonBlocking(uint32_t base, uint16_t data)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Send a char.
    //
    HWREG(base + SCI_O_THR) = data;
}

//*****************************************************************************
//
//! Gets current receiver status flags.
//!
//! \param base is the base address of the SCI port.
//!
//! \return Returns a bitwise OR combination of the receiver status flags,
//! \b SCI_RXSTATUS_READY, \b SCI_RXSTATUS_OVERRUN, \b SCI_RXSTATUS_PARITY,
//! \b SCI_RXSTATUS_FRAMING, \b SCI_RXSTATUS_BREAK, \b SCI_RXSTATUS_ADDR_RCVD.
//
//*****************************************************************************
static inline uint16_t SCI_getRxStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return the current value of the receive status register.
    //
    return (HWREG(base + SCI_O_LSR));
}

//*****************************************************************************
//
//! Waits for a character from the specified port when the FIFO enhancement
//! is enabled.
//!
//! \param base is the base address of the SCI port.
//!
//! Gets a character from the receive FIFO for the specified port.  If there
//! are no characters available, this function waits until a character is
//! received before returning. Returns immediately in case of Error.
//!
//! \return Returns the character read from the specified port as \e uint16_t
//!         or 0x0 in case of Error. The application must use
//!         SCI_getRxStatus() API to check if some error occurred before
//!         consuming the data
//
//*****************************************************************************
static inline uint16_t SCI_readCharBlockingFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Wait until a character is available in the receive FIFO.
    //
    while (SCI_getRxFIFOStatus(base) == 0)
    {
        //
        // If there is any error return
        //
        if ((SCI_getRxStatus(base) & SCI_RXSTATUS_ERROR) != 0U)
        {
            return (0U);
        }
    }

    //
    // Return the character from the receive buffer.
    //
    return HWREG(base + SCI_O_RBR);
}

//*****************************************************************************
//
//! Waits for a character from the specified port when the FIFO enhancement
//! is not enabled.
//!
//! \param base is the base address of the SCI port.
//!
//! Gets a character from the receive buffer for the specified port.  If there
//! is no characters available, this function waits until a character is
//! received before returning.
//!
//! \return Returns the character read from the specified port as \e uint16_t.
//
//*****************************************************************************
static inline uint16_t SCI_readCharBlockingNonFIFO(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Wait until a character is available in the receive FIFO.
    //
    while (!SCI_isDataAvailableNonFIFO(base))
    { }

    //
    // Return the character from the receive buffer.
    //
    return HWREG(base + SCI_O_RBR);
}

//*****************************************************************************
//
//! Receives a character from the specified port.
//!
//! \param base is the base address of the SCI port.
//!
//! Gets a character from the receive buffer for the specified port. This
//! function does not block and only reads the receive buffer.  The user should
//! use SCI_isDataAvailableNonFIFO() or SCI_getRxFIFOStatus() to determine if
//! the receive buffer or FIFO have data available.
//!
//! \return Returns \e uin16_t which is read from the receive buffer.
//
//*****************************************************************************
static inline uint16_t SCI_readCharNonBlocking(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return the character from the receive buffer.
    //
    return HWREG(base + SCI_O_RBR);
}

//*****************************************************************************
//
//! Enables Loop Back Test Mode
//!
//! \param base is the base address of the SCI port.
//!
//! Enables the loop back test mode where the Tx pin is internally connected
//! to the Rx pin.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_enableLoopback(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Set the loop back mode.
    //
    HWREG(base + SCI_O_MCR) |= SCI_MCR_LOOPBACK;
}

//*****************************************************************************
//
//! Disables Loop Back Test Mode
//!
//! \param base is the base address of the SCI port.
//!
//! Disables the loop back test mode where the Tx pin is no longer internally
//! connected to the Rx pin.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_disableLoopback(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Clear the loop back mode.
    //
    HWREG(base + SCI_O_MCR) &= ~SCI_MCR_LOOPBACK;
}

//*****************************************************************************
//
//! Get the receive FIFO Overflow flag status
//!
//! \param base is the base address of the SCI port.
//!
//! This functions gets the receive FIFO overflow flag status.
//!
//! \return Returns \b true if overflow has occurred, else returned \b false if
//! an overflow hasn't occurred.
//
//*****************************************************************************
static inline bool SCI_getOverflowStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Return the current FIFO overflow status
    //
    return (HWREG(base + SCI_O_LSR) & SCI_LSR_OE);
}

//*****************************************************************************
//
//! Clear the receive FIFO Overflow flag status
//!
//! \param base is the base address of the SCI port.
//!
//! This functions clears the receive FIFO overflow flag status.
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_clearOverflowStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Clear the current FIFO overflow status
    //
    uint32_t tmp = HWREG(base + SCI_O_LSR);
}

//*****************************************************************************
//
//! Sets the configuration of a SCI.
//!
//! \param base is the base address of the SCI port.
//! \param lspclkHz is the rate of the clock supplied to the SCI module.  This
//! is the LSPCLK.
//! \param baud is the desired baud rate.
//! \param config is the data format for the port (number of data bits,
//! number of stop bits, and parity).
//!
//! This function configures the SCI for operation in the specified data
//! format.  The baud rate is provided in the \e baud parameter and the data
//! format in the \e config parameter.
//!
//! The \e config parameter is the bitwise OR of three values: the number of
//! data bits, the number of stop bits, and the parity.  \b SCI_CONFIG_WLEN_8,
//! \b SCI_CONFIG_WLEN_7, \b SCI_CONFIG_WLEN_6, \b SCI_CONFIG_WLEN_5
//! \b Select from eight to one data bits per byte (respectively).
//! \b SCI_CONFIG_STOP_ONE and \b SCI_CONFIG_STOP_TWO select one or two stop
//! bits (respectively).  \b SCI_CONFIG_PAR_NONE, \b SCI_CONFIG_PAR_EVEN,
//! \b SCI_CONFIG_PAR_ODD, select the parity mode (no parity bit, even parity
//! bit, odd parity bit respectively).
//!
//! The peripheral clock is the low speed peripheral clock.  This will be
//! the value returned by SysCtl_getLowSpeedClock(), or it can be explicitly
//! hard coded if it is constant and known (to save the code/execution overhead
//! of a call to SysCtl_getLowSpeedClock()).
//!
//! A baud rate divider (BRR) is used in this function to calculate the
//! baud rate. The value of BRR is calculated in float and type casted as int
//! to be fed in the \b SCIHBAUD and  \b SCILBAUD registers. This conversion
//! brings an error in the calculated baud rate and the requested. Error will
//! be significant when operating at higher baud rates. The error is due to
//! lower BRR integer value granularity at higher baud rates.
//!
//! \return None.
//
//*****************************************************************************
extern void SCI_setConfig(uint32_t base, uint32_t lspclkHz, uint32_t baud, uint32_t config);

//*****************************************************************************
//
//! Waits to send an array of characters from the specified port.
//!
//! \param base is the base address of the SCI port.
//! \param array is the address of the array of characters to be transmitted.
//!   It is pointer to the array of characters to be transmitted.
//! \param length is the length of the array, or number of characters in the
//!   array to be transmitted.
//!
//! Sends the number of characters specified by \e length, starting at the
//! address \e array, out of the transmit buffer for the specified port.
//! If there is no space available in the transmit buffer, or the transmit
//! FIFO if it is enabled, this function waits until there is space available
//! and \e length number of characters are transmitted before returning.
//! \e array is a pointer to uint16_ts but only the least significant 8 bits
//! are written to the SCI port.  SCI only transmits 8 bit characters.
//!
//! \return None.
//
//*****************************************************************************
extern void SCI_writeCharArray(uint32_t base, void *array, uint16_t length);

//*****************************************************************************
//
//! Waits to receive an array of characters from the specified port.
//!
//! \param base is the base address of the SCI port.
//! \param array is the address of the array of characters to be received.
//!   It is a pointer to the array of characters to be received.
//! \param length is the length of the array, or number of characters in the
//!   array to be received.
//!
//! Receives an array of characters from the receive buffer for the specified
//! port, and stores them as an array of characters starting at address
//! \e array.  This function waits until the \e length number of characters are
//! received before returning.
//!
//! \return None.
//
//*****************************************************************************
extern void SCI_readCharArray(uint32_t base, void *array, uint16_t length);

//*****************************************************************************
//
//! Enables individual SCI interrupt sources.
//!
//! \param base is the base address of the SCI port.
//! \param intFlags is the bit mask of the interrupt sources to be enabled.
//!
//! Enables the indicated SCI interrupt sources.  Only the sources that are
//! enabled can be reflected to the processor interrupt; disabled sources have
//! no effect on the processor.
//!
//! The \e intFlags parameter is the bitwise OR of any of the following:
//!
//! - \b SCI_INT_RXERR - Recv Line Status interrupt
//! - \b SCI_INT_RXRDY - RXRDY Interrupt
//! - \b SCI_INT_TXRDY - TXRDY Interrupt
//! - \b SCI_INT_MSI   - Modem Status interrupt
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_enableInterrupt(uint32_t base, uint32_t intFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(SCI_isBaseValid(base));

    //
    // Clear the loop back mode.
    //
    HWREG(base + SCI_O_IER) |= intFlags;
}

//*****************************************************************************
//
//! Disables individual SCI interrupt sources.
//!
//! \param base is the base address of the SCI port.
//! \param intFlags is the bit mask of the interrupt sources to be disabled.
//!
//! Disables the indicated SCI interrupt sources.  Only the sources that are
//! enabled can be reflected to the processor interrupt; disabled sources have
//! no effect on the processor.
//!
//! The \e intFlags parameter has the same definition as the \e intFlags
//! parameter to SCI_enableInterrupt().
//!
//! \return None.
//
//*****************************************************************************
static inline void SCI_disableInterrupt(uint32_t base, uint32_t intFlags)
{
    HWREG(base + SCI_O_IER) &= ~intFlags;
}

//*****************************************************************************
//
//! Gets the current interrupt status.
//!
//! \param base is the base address of the SCI port.
//!
//! \return Returns the current interrupt status, enumerated as a bit field of
//! values described in SCI_enableInterrupt().
//
//*****************************************************************************
static inline uint32_t SCI_getInterruptStatus(uint32_t base)
{
    return (HWREG(base + SCI_O_IIR) & SCI_IIR_INTID_M);
}

//*****************************************************************************
//
//! Clears SCI interrupt sources.
//!
//! \param base is the base address of the SCI port.
//! \param intFlags is a bit mask of the interrupt sources to be cleared.
//!
//! The specified SCI interrupt sources are cleared, so that they no longer
//! assert.  This function must be called in the interrupt handler to keep the
//! interrupt from being recognized again immediately upon exit.
//!
//! The \e intFlags parameter has the same definition as the \e intFlags
//! parameter to SCI_enableInterrupt().
//!
//! \return None.
//
//*****************************************************************************
static void SCI_clearInterruptStatus(uint32_t base, uint32_t intFlags)
{
    uint32_t tmp = HWREG(base + SCI_O_IIR);
}

//*****************************************************************************
//
//! Sets SCI Baud rate.
//!
//! \param base is the base address of the SCI port.
//! \param lspclkHz is the rate of the clock supplied to the SCI module.  This
//! is the LSPCLK.
//! \param baud is the desired baud rate.
//!
//! This function configures the SCI for operation in the specified baud rate
//! The baud rate is provided in the \e baud parameter.
//!
//! The peripheral clock is the low speed peripheral clock.  This will be
//! the value returned by SysCtl_getLowSpeedClock()
//!
//! \return None.
//
//*****************************************************************************
extern void SCI_setBaud(uint32_t base, uint32_t lspclkHz, uint32_t baud);

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************

// for support TI code

static inline void SCI_enableModule(uint32_t base)
{ }

static inline void SCI_disableModule(uint32_t base)
{ }

static inline void SCI_performSoftwareReset(uint32_t base)
{ }

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
}
#endif

#endif
